package com.sluggard.common.utils;

import com.sluggard.common.adapter.GrantedAuthorityTypeAdapter;
import com.sluggard.common.adapter.LocalDateTypeAdapter;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.GrantedAuthority;

import java.lang.reflect.Type;
import java.time.LocalDateTime;

/**
 * description:
 * gson为线程安全的类，所以可以使用工具类来减少对象的实例化
 *
 * @author wkGui
 */
@Slf4j
public class GsonUtil {

    private static final Gson filterNullGson;
    private static final Gson nullableGson;

    static {
        GsonBuilder nullableGsonBuilder = new GsonBuilder()
                .enableComplexMapKeySerialization()
                .serializeNulls()
                .setDateFormat("yyyy-MM-dd HH:mm:ss:SSS")
                .registerTypeAdapter(LocalDateTime.class, new LocalDateTypeAdapter());
        GsonBuilder filterNullGsonBuilder = new GsonBuilder()
                .enableComplexMapKeySerialization()
                .setDateFormat("yyyy-MM-dd HH:mm:ss:SSS")
                .registerTypeAdapter(LocalDateTime.class, new LocalDateTypeAdapter());
        try {
            Class.forName("org.springframework.security.core.GrantedAuthority");
            nullableGsonBuilder.registerTypeAdapter(GrantedAuthority.class, new GrantedAuthorityTypeAdapter());
            filterNullGsonBuilder.registerTypeAdapter(GrantedAuthority.class, new GrantedAuthorityTypeAdapter());
        } catch (ClassNotFoundException e) {
            log.error("未找到GrantedAuthority类，请检查是否引入了spring-security-core依赖");
        }
        nullableGson = nullableGsonBuilder.create();
        filterNullGson = filterNullGsonBuilder.create();
    }

    protected GsonUtil() {

    }

    /**
     * 根据对象返回json   不过滤空值字段
     */
    public static String toJsonWtihNullField(Object obj) {
        return nullableGson.toJson(obj);
    }

    /**
     * 根据对象返回json  过滤空值字段
     */
    public static String toJsonFilterNullField(Object obj) {
        return filterNullGson.toJson(obj);
    }

    /**
     * 将json转化为对应的实体对象
     * new TypeToken<HashMap<String, Object>>(){}.getType()
     */
    public static <T> T fromJson(String json, Class<T> clazz) {
        return nullableGson.fromJson(json, clazz);
    }

    /**
     * 将json转化为对应的实体对象
     * new TypeToken<HashMap<String, Object>>(){}.getType()
     */
    public static <T> T fromJson(String json, Type type) {
        return nullableGson.fromJson(json, type);
    }
}

